package transforms;

import java.util.Iterator;

import org.apache.bcel.generic.ClassGen;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.MethodNode;

import com.rshacking.rhf.files.ClassContainer;
import com.rshacking.rhf.updater.Transform;
import com.rshacking.rhf.updater.hooks.ClassHook;
import com.rshacking.rhf.updater.hooks.HooksList;
import com.rshacking.rhf.updater.instructions.InsnCondition;
import com.rshacking.rhf.updater.instructions.InstructionFinder;

public class PlayerTransform extends Transform {

	@Override
	public boolean canActivate(final HooksList hooks, final ClassContainer cc) {
		return new ClassGen(cc.getBCEL()).getConstantPool().lookupUtf8("nsn0") > 0;
	}

	@Override
	public boolean execute(final HooksList hooks, final ClassContainer cc) {
		ClassHook client = null;
		if (hooks.contains("Client")) {
            client = hooks.get("Client");
        } else {
            client = hooks.add("Client", "client");
        }
		final ClassNode cn = cc.getASM();
		final Iterator<MethodNode> it = cn.methods.iterator();
		while (it.hasNext()) {
			final MethodNode mn = it.next();
			if ((mn.access & ACC_STATIC) == 0) {
                continue;
            }
			final InstructionFinder<AbstractInsnNode> finder = new InstructionFinder<AbstractInsnNode>(
					mn, true);
			if (finder.getNext(InsnCondition.ASM.makeLDCCond("nsn0")) == null) {
                continue;
            }
			finder.reset(false);
			FieldInsnNode fin = null;
			fin = (FieldInsnNode) finder
					.getPrev(InsnCondition.ASM.GETSTATIC_IA);
			if (fin != null) {
                client.add("playerIndices", fin);
            }
			fin = (FieldInsnNode) finder.getNext(InsnCondition.ASM.GETSTATIC_I);
			if (fin != null) {
                client.add("playerCount", fin);
            }
			fin = (FieldInsnNode) finder
					.getPrev(InsnCondition.ASM.GETSTATIC_LA);
			if (fin != null) {
				hooks.add("Player", fin.desc);
				client.add("players", fin);
				
			}
			return true;
		}
		return false;
	}

}